/* * Copyright (c) 2013 Menny Even-Danan * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.anysoftkeyboard.keyboards; import android.view.KeyEvent; import com.anysoftkeyboard.AnySoftKeyboard; import com.anysoftkeyboard.api.KeyCodes; import com.anysoftkeyboard.keyboards.KeyEventStateMachine.State; import com.menny.android.anysoftkeyboard.AnyApplication; import java.security.InvalidParameterException; public class HardKeyboardSequenceHandler { private static final int[] msQwerty = new int[]{ KeyEvent.KEYCODE_Q, KeyEvent.KEYCODE_W, KeyEvent.KEYCODE_E, KeyEvent.KEYCODE_R, KeyEvent.KEYCODE_T, KeyEvent.KEYCODE_Y, KeyEvent.KEYCODE_U, KeyEvent.KEYCODE_I, KeyEvent.KEYCODE_O, KeyEvent.KEYCODE_P, KeyEvent.KEYCODE_A, KeyEvent.KEYCODE_S, KeyEvent.KEYCODE_D, KeyEvent.KEYCODE_F, KeyEvent.KEYCODE_G, KeyEvent.KEYCODE_H, KeyEvent.KEYCODE_J, KeyEvent.KEYCODE_K, KeyEvent.KEYCODE_L, KeyEvent.KEYCODE_Z, KeyEvent.KEYCODE_X, KeyEvent.KEYCODE_C, KeyEvent.KEYCODE_V, KeyEvent.KEYCODE_B, KeyEvent.KEYCODE_N, KeyEvent.KEYCODE_M }; //See 'getSequenceCharacter' function for usage for msSequenceLivingTime and mLastTypedKeyEventTime. //private static final long msSequenceLivingTime = 600; private long mLastTypedKeyEventTime; private final KeyEventStateMachine mCurrentSequence; public HardKeyboardSequenceHandler() { mCurrentSequence = new KeyEventStateMachine(); mLastTypedKeyEventTime = System.currentTimeMillis(); } public void addQwertyTranslation(String targetCharacters) { if (msQwerty.length != targetCharacters.length()) throw new InvalidParameterException("'targetCharacters' should be the same length as the latin QWERTY keys strings: " + msQwerty); for (int qwertyIndex = 0; qwertyIndex < msQwerty.length; qwertyIndex++) { char latinCharacter = (char) msQwerty[qwertyIndex]; char otherCharacter = targetCharacters.charAt(qwertyIndex); if (otherCharacter > 0) { this.addSequence(new int[]{latinCharacter}, otherCharacter); this.addSequence(new int[]{KeyCodes.SHIFT, latinCharacter}, Character.toUpperCase(otherCharacter)); } } } public void addSequence(int[] sequence, int result) { this.mCurrentSequence.addSequence(sequence, result); } public void addShiftSequence(int[] sequence, int result) { this.mCurrentSequence.addSpecialKeySequence(sequence, KeyCodes.SHIFT, result); } public void addAltSequence(int[] sequence, int result) { this.mCurrentSequence.addSpecialKeySequence(sequence, KeyCodes.ALT, result); } private State addNewKey(int currentKeyEvent) { //sequence does not live forever! //I say, let it live for msSequenceLivingTime milliseconds. long currentTime = System.currentTimeMillis(); if ((currentTime - mLastTypedKeyEventTime) >= AnyApplication.getConfig().getMultiTapTimeout()) mCurrentSequence.reset(); mLastTypedKeyEventTime = currentTime; return mCurrentSequence.addKeyCode(currentKeyEvent); } public boolean addSpecialKey(int currentKeyEvent) { State result = this.addNewKey(currentKeyEvent); return (result != State.RESET); } public int getCurrentCharacter(int currentKeyEvent, AnySoftKeyboard inputHandler) { State result = this.addNewKey(currentKeyEvent); if (result == State.FULL_MATCH || result == State.PART_MATCH) { int mappedChar = mCurrentSequence.getCharacter(); final int charactersToDelete = mCurrentSequence.getSequenceLength() - 1; if (charactersToDelete > 0) inputHandler.deleteLastCharactersFromInput(charactersToDelete); return mappedChar; } return 0; } }